iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
Software Development

從 C++ 菜鳥到 Low-Latency 勇者:一場分秒必爭的賽局系列 第 19

[Day 19] High-Performance Concurrency: Thread Pinning II

  • 分享至 

  • xImage
  •  

Thread pinning 並不只是「把 thread 綁到某顆 CPU」這麼簡單,其核心概念可以濃縮成三句話:

  • CPU affinity 限制 thread 可以執行的位置。
  • CPU isolation 則進一步降低 critical CPU 所承受的外部干擾。
  • 真正的低延遲設計還必須同時考慮 SMT、IRQ、NUMA、cache locality 及 memory placement。

1. SMT —— Pin 到 Logical CPU 還不夠

Day 18 已經有提到 CPU affinity 及 CPU isolation,而另一個常被忽略的因素是 simultaneous multithreading (SMT)。

假設一個 CPU core 與 thread 的分配如下:

Physical Core 0
ㅤ├── CPU 0
ㅤ└── CPU 8

Thread A → CPU 0
Thread B → CPU 8

CPU 0 與 CPU 8 雖然是兩個 logical CPU,但並不代表它們真的擁有兩個完全獨立的 physical cores,其背後共享部分 execution resources。如果 Thread A 是極度 latency-sensitive workload,而 Thread B 正在消耗大量資源,那麼兩者仍可能互相影響。

CPU affinity 只是最上層的一個控制手段。所以在做 CPU isolation 時,必須理解:
logical CPU → SMT sibling → physical core → CPU package → NUMA node

2. NUMA —— 另一個維度

在多 multi-socket server 上,CPU 與 memory 通常具有 NUMA topology。為了方便理解,我們可以參考以下常見的雙節點架構範例:

NUMA Node 0
ㅤ├── CPU 0-15
ㅤ└── Memory 0

NUMA Node 1
ㅤ├── CPU 16-31
ㅤ└── Memory 1

當 thread 跑在 Node 0 時,如果它存取的資料位於本地的 Memory 0,就具有最佳的 locality。相反地,若所需資料大量配置在 Memory 1,那麼 CPU 0-15 讀取該資料時就可能產生 remote memory access,進而拉高 latency。

因此,在高效能系統中 thread placement 和 memory placement 往往需要一起考慮。CPU affinity 解決 thread 在哪裡跑;而 NUMA policy 則進一步處理資料的位置。

3. 什麼情況值得使用 Thread Pinning?

Thread pinning 並不是越多越好。一般 web application 沒有必要手動 pin 每一條 worker thread,因為 scheduler 自己進行 load balancing,往往更符合整體 throughput 需求:
HTTP request → business logic → database

比較值得考慮的場景包括:

  • Ultra-low-latency networking
  • High-frequency data processing
  • Packet processing
  • Real-time audio
  • Game engine critical loop
  • High-performance storage
  • Market-data processing
  • Telemetry pipeline
  • Embedded real-time systems
  • Latency-sensitive middleware

其共同特徵是 tail latency 比單純平均 throughput 更重要。即使平均值只改善一點點,tail latency 若能大幅收斂,對某些系統而言仍然可能具有實際價值。

因此 Thread pinning 真正要解決的問題不是讓 CPU 跑得更快,而是讓 execution behavior 更可預測。

4. Pinning 的代價

雖然 scheduler 有能力做 dynamic load balancing,但實務上卻不適合把 thread 全部 pin 起來,因為 pinning 同樣會帶來代價。

假設某個 thread 被固定在 CPU 0,其他 CPU 使用率如下表。即使 CPU 1-3 都很閒,這個 thread 也不能自行移動。
CPU 0ㅤㅤ100%
CPU 1ㅤㅤ20%
CPU 2ㅤㅤ15%
CPU 3ㅤㅤ10%

這就是 affinity 帶來的 flexibility trade-off。Thread pinning 其實是以 scheduler flexibility 換取 execution locality 與 predictability。如果配置錯誤,反而可能降低 throughput。

5. 真正的 High-Performance Design

綜上所述,一個成熟的架構不是所有 thread 都隨意 pin。Thread pinning 不再是一個單獨的 optimization trick,而是整個 CPU placement strategy 的一部分。

                 CPU Topology
                      │
          ┌──────┴───────┐
          │                       │
   housekeeping CPUs       isolated CPUs
          │                       │
    OS / IRQ / misc          critical work
                                  │
                     ┌───────┴───────┐
                     │                         │
                RX thread                 worker thread
                     │                         │
                CPU affinity              CPU affinity
                     │                         │
                     └──────┬────────┘
                                 │
                            NUMA locality

下一篇文我們會從理論進入到實作:如何在 Linux 上配置 CPU affinity、isolated CPU、IRQ affinity,以及如何用 benchmark、tasksetpthread_setaffinity_np() 與 profiling tools 驗證 pinning 是否真的降低了 scheduler jitter。


上一篇
[Day 18] High-Performance Concurrency: Thread Pinning I
下一篇
[Day 20] High-Performance Concurrency: Linux CPU Scheduling
系列文
從 C++ 菜鳥到 Low-Latency 勇者:一場分秒必爭的賽局21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言